package com.cdut.config;

import com.cdut.interceptor.RememberMeInterceptor;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro的配置类
 */

/*
subject用户
SecurityManager 管理所有的用户
realm 连接数据
 */

//----------------需要改

@Configuration
public class ShiroConfig {
    //shiroFilterFactoryBean 3.
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager,
                                                            @Qualifier("rememberMeManager")RememberMeManager rememberMeManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);


        //添加shiro的内置过滤器
        /*
         anon无需认证就可以访问
         authc:必须认证了才可以访问
         user: 必须拥有了记住我功能后才可以用
         perm: 拥有对某个资源的权限才可以访问
         role: 拥有某个角色的权限才可以访问
         */

        Map<String,String> filterMap= new LinkedHashMap<String,String>();

        /*
        拦截设置
         */
        //filterMap.put("/shoppingcart/**","authc");

        filterMap.put("/shoppingcart/**","user");



        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        //设置认证页面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        return shiroFilterFactoryBean;
    }

    //DefaultWebSecurityManager 2.
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);

        //记住我
        securityManager.setRememberMeManager(rememberMeManager());

        return securityManager;
    }


    //常见realm对象 1.
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }


    ////记住我
    //@Bean(name = "rememberMeManager")
    //public CookieRememberMeManager rememberMeManager(){
    //    CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
    //    cookieRememberMeManager.setCookie(rememberMeCookie());
    //    //这个地方有点坑，不是所有的base64编码都可以用，长度过大过小都不行，没搞明白，官网给出的要么0x开头十六进制，要么base64
    //    cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));
    //    return cookieRememberMeManager;
    //}


    @Bean(name = "rememberMeManager")
    public RememberMeManager rememberMeManager() {
        CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
        //注入自定义cookie(主要是设置寿命, 默认的一年太长)
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setHttpOnly(true);

        //设置RememberMe的cookie有效期
        simpleCookie.setMaxAge(100000);
        rememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));

        rememberMeManager.setCookie(simpleCookie);

        return rememberMeManager;
    }


    //cookie管理
    @Bean
    public SimpleCookie rememberMeCookie(){
        //这个参数是cookie的名称，对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //setcookie的httponly属性如果设为true的话，会增加对xss防护的安全系数。它有以下特点：

        //setcookie()的第七个参数
        //设为true后，只能通过http访问，javascript无法访问
        //防止xss读取cookie
        simpleCookie.setMaxAge(604800);
        simpleCookie.setHttpOnly(true);
        return simpleCookie;
    }

    /**
     * FormAuthenticationFilter 过滤器 过滤记住我
     */
    @Bean
    public FormAuthenticationFilter formAuthenticationFilter(){
        FormAuthenticationFilter formAuthenticationFilter = new FormAuthenticationFilter();
        //对应前端的checkbox的name = rememberMe
        formAuthenticationFilter.setRememberMeParam("rememberMe");
        return formAuthenticationFilter;
    }

    /**
     * 自动登录将用户加到session中
     */
    @Bean(name = "rememberMeInterceptor")
    public RememberMeInterceptor sessionInterceptor() {
        return new RememberMeInterceptor();
    }
}

